local skynet = require "skynet"
local timer = require "timer"
local base = require "base"
local timetool = require "timetool"
local filelog = require "filelog"
require "pubenum"
require "sssenum"


local tabletimer = {
    server = nil,
}

function tabletimer.init(service)
    if tabletimer.server == nil then
        tabletimer.server = service
    end
end

function tabletimer.timer(msgname, timerid, noticemsg)
	local f = tabletimer[msgname]
	if f and type(f) == "function" then
		f(timerid, noticemsg)
	end
end

function tabletimer.doready(timerid, noticemsg)
    local server = tabletimer.server
    local table_data = server.table_data
    if table_data.conf.table_index ~= noticemsg.table_index then
        return
    end
    local seat = table_data.seats[noticemsg.seat_index]
    if not seat or seat.rid ~= noticemsg.rid then
        return
    end
    if timerid ~= seat.ready_timer_id then
        return 
    end
    seat.ready_timer_id = -1
    local tablelogic = server:get_logicbyname("tablelogic")
    for index, playerseat in ipairs(table_data.seats) do
        if playerseat.rid > 0 and playerseat.playerinfo and playerseat.playerinfo.level ~= 99 then
            local status, ridmap = skynet.pcall(skynet.call, ".router", "lua", "get_role_data", nil, playerseat.rid)
            if status == true and ridmap and next(ridmap) ~= nil then
                if not ridmap.table_index or ridmap.table_index ~= table_data.conf.table_index then
                    tablelogic.passive_standuptable(table_data, nil, playerseat, SSSEStandupReason.STANDUP_REASON_TABLE_CHUANZHUO)
                end
            else
                tablelogic.passive_standuptable(table_data, nil, playerseat, SSSEStandupReason.STANDUP_REASON_TABLE_CHUANZHUO)
            end
        end
    end
    if table_data.conf.table_type == SSSTableType.TABLE_TYPE_FANGKA then
        if table_data.curr_to_num >= 1 then
            seat.state = SSSSeatState.SEAT_STATE_WAIT_START
            if seat.ready_timer_id > 0  then ---取消准备倒计时
                timer.cleartimer(seat.ready_timer_id)
                seat.ready_timer_id = -1
            end
            ---有操作,更新心跳时间
            server:update_heart_time()
            tablelogic.gameready(table_data, {}, seat, noticemsg.playerdata)
        else
            ----tablelogic.passive_standuptable(table_data, nil, seat, SSSEStandupReason.STANDUP_REASON_READYTIMEOUT_STANDUP)
        end
    elseif table_data.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI or table_data.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
        if noticemsg.is_matching == true then
            if seat.state == SSSSeatState.SEAT_STATE_WAIT_READY then
                seat.state = SSSSeatState.SEAT_STATE_WAIT_START
	            if seat.ready_timer_id > 0  then ---取消准备倒计时
		            timer.cleartimer(seat.ready_timer_id)
		            seat.ready_timer_id = -1
                end
                ---有操作,更新心跳时间
	            server:update_heart_time()
	            tablelogic.gameready(table_data, {}, seat, noticemsg.playerdata)
            end
        else
            ---是自建钻石场就先踢出玩家
            tablelogic.passive_standuptable(table_data, nil, seat, SSSEStandupReason.STANDUP_REASON_READYTIMEOUT_STANDUP)
        end
    elseif table_data.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
        if noticemsg.is_matching == true then
            if seat.state == SSSSeatState.SEAT_STATE_WAIT_READY then
                seat.state = SSSSeatState.SEAT_STATE_WAIT_START
	            if seat.ready_timer_id > 0  then ---取消准备倒计时
		            timer.cleartimer(seat.ready_timer_id)
		            seat.ready_timer_id = -1
                end
                ---有操作,更新心跳时间
	            server:update_heart_time()
	            tablelogic.gameready(table_data, {}, seat, noticemsg.playerdata)
            end
        else ---如果不是在匹配中,超时没有准备则踢出牌桌
            tablelogic.passive_standuptable(table_data, nil, seat, SSSEStandupReason.STANDUP_REASON_READYTIMEOUT_STANDUP)
        end
    end
    if table_data.conf.table_type == SSSTableType.TABLE_TYPE_ZUANSI then
        tablelogic.check_has_enough_diamond(table_data)
    elseif table_data.conf.table_type == SSSTableType.TABLE_TYPE_ZJZUANSI then
        tablelogic.check_has_enough_diamond(table_data)
    elseif table_data.conf.table_type == SSSTableType.TABLE_TYPE_COIN then
        tablelogic.check_has_enough_coin()
    end
    if not tablelogic.has_real_player() then
		for index, seat in ipairs(table_data.seats) do
			if seat.rid ~= 0 and seat.is_mirror == true and seat.state == SSSSeatState.SEAT_STATE_WAIT_START then
				seat.state = SSSSeatState.SEAT_STATE_WAIT_READY
				seat.ready_to_time = 0
				if seat.ready_timer_id > 0 then
					timer.cleartimer(seat.ready_timer_id)
					seat.ready_to_time = -1
				end
			end
		end
	end

    local is_allready = tablelogic.check_all_ready(table_data)
	local readynum = 0
	for k, v in ipairs(table_data.seats) do
		if v.rid ~= 0 and v.state == SSSSeatState.SEAT_STATE_WAIT_START then
			readynum = readynum + 1
		end
    end
    ---filelog.sys_error("-------is_allready-------", seat.rid, is_allready, readynum)
	if readynum > 1  and is_allready == true and table_data.state == SSSTableState.TABLE_STATE_WAIT_ALL_READY then
		table_data.is_can_kick = false
		table_data.state = SSSTableState.TABLE_STATE_ONE_GAME_START
		local gamelogic = tablelogic.get_gamelogic()
		gamelogic.run(table_data.gamelogic)
	end
end


function tabletimer.one_game_start(timerid, noticemsg)
    local server = tabletimer.server
	local table_data = server.table_data
	if timerid ~= table_data.timer_id then
		return
	end
    table_data.timer_id = -1
	if table_data.state ~= SSSTableState.TABLE_STATE_ONE_WAIT_GAME_START then
		return
	end
    local tablelogic = server:get_logicbyname("tablelogic")
    local roomgamelogic = tablelogic.get_gamelogic()
    ----发牌
    table_data.state = SSSTableState.TABLE_STATE_DEAL_ALL_CARDS    
	roomgamelogic.run(table_data.gamelogic)
end

function tabletimer.sort_card_outoftime(timerid, noticemsg)
    local server = tabletimer.server
    local table_data = server.table_data
    if table_data.conf.table_index ~= noticemsg.table_index then
        return
    end
    local seat = table_data.seats[noticemsg.seat_index]
    if not seat or seat.rid ~= noticemsg.rid then
        return
    end
    if timerid ~= seat.timer_id then
        return
    end
    seat.timer_id = -1
    if seat.state == SSSSeatState.SEAT_STATE_SORTCARDS then
        ----自动为玩家理牌
        --- to do
        ---
        local roomtablelogic = server:get_logicbyname("tablelogic")
        local replaywrite = server:get_logicbyname("replaywrite")
        local seatlogic = server:get_logicbyname("seatlogic")
        seatlogic.auto_sorted_cards(seat)
        seat.action_type = SSSActionType.ACTION_SORTCARDS
        seat.state = SSSSeatState.SEAT_STATE_SORTCARDS_OVER
        roomtablelogic.waitdoaction(table_data, nil, seat, nil)
    end
end

function tabletimer.special_auto_sort(timerid, noticemsg)
    local server = tabletimer.server
    local table_data = server.table_data
    if table_data.conf.table_index ~= noticemsg.table_index then
        return 
    end
    table_data.auto_special_timer_id = -1
    local roomseatlogic = server:get_logicbyname("seatlogic")
    filelog.sys_error("-----------tabletimer.special_auto_sort--------")
    ----检查所有玩家是否有特殊牌型
    for index, seat in ipairs(table_data.seats) do
        if roomseatlogic.is_ingame(seat) and seat.special_card_type ~= 0 then
            local roomtablelogic = server:get_logicbyname("tablelogic")
            local replaywrite = server:get_logicbyname("replaywrite")
            local seatlogic = server:get_logicbyname("seatlogic")
            seatlogic.auto_sorted_cards(seat)
            seat.action_type = SSSActionType.ACTION_SORTCARDS
            seat.state = SSSSeatState.SEAT_STATE_SORTCARDS_OVER
            roomtablelogic.waitdoaction(table_data, nil, seat, nil)
        end
    end 
end

function tabletimer.sort_cards_over(timerid, noticemsg)
    local server = tabletimer.server
    local table_data = server.table_data
    if table_data.conf.table_index ~= noticemsg.table_index then
        return
    end
    if table_data.timer_id ~= timerid then
        return
    end
    table_data.timer_id = -1
    local tablelogic = server:get_logicbyname("tablelogic")
    local gamelogic = tablelogic.get_gamelogic()
    table_data.state = SSSTableState.TABLE_STATE_ONE_GAME_END
    gamelogic.run(table_data.gamelogic)
end

function tabletimer.wait_game_end_over(timerid, noticemsg)
    local server = tabletimer.server
    local table_data = server.table_data
    if table_data.conf.table_index ~= noticemsg.table_index then
        return 
    end
    if timerid ~= table_data.timer_id then
        return 
    end
    table_data.timer_id = -1
    ---filelog.sys_error("--------tabletimer.wait_game_end_over------")
    local roomtablelogic = server:get_logicbyname("tablelogic")
    local roomgamelogic = roomtablelogic.get_gamelogic()
    table_data.state = SSSTableState.TABLE_STATE_ONE_GAME_END_AFTER
    roomgamelogic.run(table_data.gamelogic)
end

function tabletimer.qiangzhuang_delay(timerid, noticemsg)
    local server = tabletimer.server
    local table_data = server.table_data
    if table_data.conf.table_index ~= noticemsg.table_index then
        return 
    end
    if timerid ~= table_data.timer_id then
        return
    end
    table_data.timer_id = -1
    ----判断是什么玩法，如果是自由抢庄，那么通知玩家下注，如果是看牌抢庄，那么就改通知玩家下注
    if table_data.conf.play_game_type == DNQZType.QZ_TYPE_FREE then
        ---自由抢庄
		table_data.state = SSSTableState.DN_TABLE_STATE_XIAZHU
    elseif table_data.conf.play_game_type == DNQZType.QZ_TYPE_KANPAI then
        ---看牌抢庄
        table_data.state = SSSTableState.DN_TABLE_STATE_XIAZHU
    end
    local tablelogic = server:get_logicbyname("tablelogic")
	local roomgamelogic = tablelogic.get_gamelogic()
	roomgamelogic.run(table_data.gamelogic)
end

function tabletimer.delete_table(timerid, noticemsg)
    local server = tabletimer.server
    local table_data = server.table_data
    if noticemsg.table_index ~= table_data.conf.table_index then
        return
    end
    if timerid ~= table_data.delete_table_timer_id then
        return 
    end
    table_data.delete_table_timer_id = -1
    server:process("delete", noticemsg.reason)
end

function tabletimer.train_add_mirror(timer_id, noticemsg)
    local server = tabletimer.server
    local table_data = server.table_data
    if timer_id ~= table_data.timer_id then
        return
    end
    table_data.timer_id = -1
    if noticemsg.table_index ~= table_data.conf.table_index then
        return
    end
    local trainlogic = server:get_logicbyname("trainlogic")
    if noticemsg.neednum > 0 then
        trainlogic.entersittable(noticemsg.neednum)
    end
end

function tabletimer.mirror_doready(timerid, noticemsg)
    local server = tabletimer.server
    local table_data = server.table_data
    if table_data.conf.table_index ~= noticemsg.table_index then
        return
    end
    local seat = table_data.seats[noticemsg.seat_index]
    if not seat or seat.rid ~= noticemsg.rid then
        return
    end
    if timerid ~= seat.ready_timer_id then
        return 
    end
    seat.ready_timer_id = -1
    local trainlogic = server:get_logicbyname("trainlogic")
    local tablelogic = server:get_logicbyname("tablelogic")
    if not table_data.conf.is_train_diamond or table_data.conf.is_train_diamond == 0 then
        if tablelogic.has_real_player() then
            trainlogic.do_ready(seat.rid)
        end
    else
        trainlogic.do_ready(seat.rid)
    end
end

function tabletimer.timer_cancle_table(timerid, noticemsg)
    local server = tabletimer.server
    local table_data = server.table_data
    local tablelogic = server:get_logicbyname("tablelogic")
    if table_data.conf.table_index ~= noticemsg.table_index then
        return 
    end
    local seat = tablelogic.get_seat_by_rid(table_data, noticemsg.rid)
    if not seat or seat.rid ~= noticemsg.rid then 
        return 
    end
    local rids = tablelogic.getallrids(table_data)
    ----记录玩家在这轮的操作
    table_data.cancel_tableinfo[seat.index] = {
                                                index = seat.index, 
                                                rid = seat.rid,
                                                rolename = seat.playerinfo.rolename, 
                                                action_type = 0,
                                            }
    table_data.cancel_tableinfo[seat.index].action_type = DNActionType.ACTION_TYPE_AGREE
    ----向其他玩家通知该玩家的操作结果
    --[[
        //广播玩家响应解散的结果
        message disbanddealN {
            optional int32 rid = 1;         //玩家rid
            optional string rolename = 2;   //玩家名字
            repeated player_disband_item player_disband_list = 3;   //玩家解散列表，所有玩家的响应情况
        }
        //响应解散的玩家信息
        message player_disband_item {
            optional int32 rid = 1;
            optional string rolename = 2;
            optional int32 is_agree = 3;        //是否同意, 1同意 2拒绝 nil未操作
        }
    --]]
    local noticemsg = {
        rid = seat.rid,
        rolename = seat.playerinfo.rolename,
        player_disband_list = {},
    }
    for index, actionobj in pairs(table_data.cancel_tableinfo) do
        local objbase = { rid = actionobj.rid, rolename = actionobj.rolename, is_agree = 0}
        if actionobj.action_type == DNActionType.ACTION_TYPE_AGREE then
            objbase.is_agree = 1
        elseif actionobj.action_type == DNActionType.ACTION_TYPE_DISAGREE then
            objbase.is_agree = 2
        end
        table.insert(noticemsg.player_disband_list, objbase)
    end
    server:send_notice_to_players(rids, "disbanddealN", noticemsg, nil, nil)

    ----判断本轮操作是否完成,完成则发送最终结果
    local isallover, lastaction, dis_index = tablelogic.check_allplayerdone()
    ----filelog.sys_error("----------isallover, lastaction, dis_index------", isallover, lastaction, dis_index)
    if isallover == true then
        --[[
            //通知解散结果
        message disbandresultN {
            optional int32 table_index = 1;     //桌号
            optional bool is_success = 2;       // 是否解散成功
        }
        --]]
        local noticeovermgs = {
            table_index = 0,
            is_success = "",
        }
        if lastaction == 2 then
            noticeovermgs.is_success = false
        elseif lastaction == 1 then
            noticeovermgs.is_success = true
        end
        ---清除玩家操作记录
        table_data.cancel_tableinfo = {}
        server:send_notice_to_players(rids, "disbandresultN", noticeovermgs, nil, nil)
        if lastaction == 1 then
            ----直接调用大结算函数
            tablelogic.do_all_balance(table_data)
            server:process("delete", "canceltable")
        end
    end
end
----延时通知
function tabletimer.delay_notice_robot_ready(timerid, noticemsg)
    local server = tabletimer.server
    local table_data = server.table_data
    local tablerobothelper = server:get_logicbyname("tablerobothelper")
    if timerid ~= table_data.notice_robot_timer_id then
        return
    end
    if table_data.conf.table_index ~= noticemsg.table_index then
        return
    end
    table_data.notice_robot_timer_id = -1
    tablerobothelper.notice_robot_ready()
end

function tabletimer.delay_notice_robot_qiangzhuang(timerid, noticemsg)
    local server = tabletimer.server
    local table_data = server.table_data
    local tablerobothelper = server:get_logicbyname("tablerobothelper")
    if timerid ~= table_data.notice_robot_timer_id then
        return
    end
    if table_data.conf.table_index ~= noticemsg.table_index then
        return 
    end
    table_data.notice_robot_timer_id = -1
    tablerobothelper.notice_robot_qiangzhuang()
end

function tabletimer.delay_notice_robot_xiazhu(timerid, noticemsg)
    local server = tabletimer.server
    local table_data = server.table_data
    local tablerobothelper = server:get_logicbyname("tablerobothelper")
    if timerid ~= table_data.notice_robot_timer_id then
        return 
    end
    if table_data.conf.table_index ~= noticemsg.table_index then
        return
    end
    table_data.notice_robot_timer_id = -1
    tablerobothelper.notice_robot_xiazhu()
end

function tabletimer.delay_notice_robot_kaipai(timerid, noticemsg)
    local server = tabletimer.server
    local table_data = server.table_data
    local tablerobothelper = server:get_logicbyname("tablerobothelper")
    if timerid ~= table_data.notice_robot_timer_id then
        return
    end
    if table_data.conf.table_index ~= noticemsg.table_index then
        return
    end
    table_data.notice_robot_timer_id = -1
    tablerobothelper.notice_robot_kaipai()
end

return tabletimer
